package com.etime.shycourse.services.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.etime.shycourse.config.Tools;
import com.etime.shycourse.dao.*;
import com.etime.shycourse.dto.CourseAndCourseTypeDto;
import com.etime.shycourse.dto.CourseOfflineDto;
import com.etime.shycourse.dto.CourseOfflineshowattrconfigDto;
import com.etime.shycourse.dto.CurrentUser;
import com.etime.shycourse.pojo.Course;
import com.etime.shycourse.pojo.Organization;
import com.etime.shycourse.pojo.Teacher;
import com.etime.shycourse.services.interfaces.CourseServices;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @author wb
 * @since 2021-12-17
 */
@Service
public class CourseServiceImpl implements CourseServices {
    @Autowired
    CourseMapper mapper;
    @Autowired
    OrgTeacherMapper tMapper;
    @Autowired
    SysUserMapper uMapper;
    @Autowired
    LessonMapper lessonMapper;
    @Autowired
    Tools tools;
    @Autowired
    OfflineshowattrconfigMapper ofMapper;
    @Autowired
    OrganizationMapper oMapper;

    /**
     * 根据courseid 查询一条课程类型数据
     */
    @Override
    public Course selectCourseById(Integer courseid) {
        return mapper.selectById(courseid);
    }

    /**
     * 根据courseid 查询一条课程+课程类型数据
     */
    @Override
    public CourseAndCourseTypeDto selectCourseAndCourseTypeById(Integer courseid) {
        return mapper.selectCourseAndCourseTypeById(courseid);
    }

    /**
     * 根据教师id，从课程表中查询出该教师所有的课程列表
     *
     * @param teacherId 教师id
     * @return List<Course>
     */
    @Override
    public List<Course> selectCourseTeacherById(Integer teacherId) {
        return mapper.selectList(new QueryWrapper<Course>().eq("courseteacherid", teacherId));
    }

    /**
     * 查询 从本机构中查询本机构所有在职老师
     *
     * @param orgId 机构id
     * @return List<Course>
     */
    @Override
    public List<Teacher> selectCourseTeacherByOrgId(Integer orgId) {
        return tMapper.selectList(new QueryWrapper<Teacher>().eq("tecorgid", orgId));
    }

    /**
     * 修改课程表中的：课程教师id 和课程教师姓名 两个字段
     *
     * @param course 中的课程id（courseid）
     * @return int
     */
    @Override
    public int updateCourse(Course course) {
        // 设置修改时间为 当前时间
        course.setCourseupdatetime(new Date());
        // 是否启用易币 1--开启 0--不开启
        if (course.getCoursecoinused() != null && course.getCoursecoinused() == 0) {
            //设置当虚拟币为空时 设置为0
            // 课程虚拟币价格 coursecoinprice
            course.setCoursecoinprice(new BigDecimal(0.00));
            // 最多使用虚拟币数量
            course.setCoursecoinmaxpoint(new BigDecimal(0.00));
        }
        return mapper.updateById(course);
    }

    /**
     * 修改教师表：教师所属机构id=-2。变更为独立教师身份。
     * <p>
     * 根据教师表 中的教师id
     **/
    @Override
    public int upDataTeacher(Teacher teacher) {
        UpdateWrapper<Teacher> set = new UpdateWrapper<Teacher>().eq("tecid", teacher.getTecid()).set("tecorgid", -2);
        // 根据条件更新 tecid ->把tecorgid(所属机构)设置为-2
        // 返回值是受影响的行数
        return tMapper.update(null, set);
    }

    /**
     * 教师只能查询自己的课程；
     * 课程（course）中，根据条件：课程教师id（courseteacherid）= 登录用户的教师id，进行查询。
     *
     * @param course 必要条件 ：改为token |课程教师id courseteacherid
     *               非必要条件：
     *               模糊查询 课程名 coursetitle
     *               课程类型查询  course 根据类型id
     *               <p></p>
     *               复用：添加
     *               查询条件：平台管理员增加：
     *               审核状态，courseaudit
     *               是否推荐，courserecommended
     *               课程状态: coursestate
     *               <p></p>
     *               课程状态 coursestate 三个查询条件；
     *               增加按（课程排序，课程评分，课程点击次数，评论次数）进行（asc/desc）排序的功能
     *               自定义 数据库中没有
     *               sort:排序 ,0=asc 1=desc
     *               SortBy:用什么排序 ,0=课程评分 coursescore ，1=课程点击次数 coursepullcount，2=评论次数 coursecommentcount。
     * @return Page<Course>
     */
    @Override
    public Page<Course> selectCoursePageBy(Course course, Long pagenum, Long pagesize, String token) {
        CurrentUser user = tools.getCurrentUserFromRedis(token);
        if (user == null) {
            return null;
        }
        /**
         * 当前端没有传分页数据时 就使用 page默认的值
         * pagesize = 1L
         * size = 10L;
         * */
        Page<Course> page;
        if (pagenum != null & pagesize != null) {
            page = new Page<>(pagenum, pagesize);
        } else {
            page = new Page<>();
        }

        /*2022 - 02 - 25 12:58:37 wb
        當前没有创建教师用户
        先注释掉 下一步创建了教师
        再进行按照教师进行课程创建管理
        */
        if (user.getTecid() != null) {
            // 课程教师id courseteacherid
            course.setCourseteacherid(user.getTecid());
        }
        return mapper.selectCoursePageBys(course, page);
    }

    /**
     * 机构课程列表
     */
    @Override
    public Page<Course> selectCoursePageBys(Course course, Long pagenum, Long pagesize, String token) {
        CurrentUser user = tools.getCurrentUserFromRedis(token);
        if (user == null) {
            return null;
        }

        /**
         * 当前端没有传分页数据时 就使用 page默认的值
         * pagesize = 1L
         * size = 10L;
         * */
        Page<Course> page;
        if (pagenum != null & pagesize != null) {
            page = new Page<>(pagenum, pagesize);
        } else {
            page = new Page<>();
        }
        // 机构查询
        if (user.getOrgid() == null) {
            course.setCourseorgid(user.getOrgid());
        }
        return mapper.selectCoursePageBys(course, page);
    }

    /**
     * 系统
     *
     * @param course 非必要条件：
     *               模糊查询 课程名 coursetitle
     *               课程类型查询  course
     *               <p>
     *               添加条件:
     *               课程状态 -1--全部  0--未发布 1--发布 2--关闭；
     *               是否推荐 -1--全部 0--不推荐 1--推荐
     *               审核状态 -1--全部 0--未审 1--通过 2--未通过；
     *               <p>
     *               增加按（课程排序，课程评分，课程点击次数，评论次数）进行（asc/desc）排序的功能
     *               自定义 数据库中没有
     *               sort:排序 ,0=asc 1=desc
     *               SortBy:用什么排序 ,0=课程评分 coursescore ，1=课程点击次数 coursepullcount，2=评论次数 coursecommentcount。
     */
    @Override
    public Page<Course> selectSysCoursePageBy(Course course, Long pagenum, Long pagesize) {
        /**
         * 当前端没有传分页数据时 就使用 page默认的值
         * pagesize = 1L
         * size = 10L;
         * */
        Page<Course> page;
        if (pagenum != null & pagesize != null) {
            page = new Page<>(pagenum, pagesize);
        } else {
            page = new Page<>();
        }
        if (course == null) {
            return mapper.selectPage(page, null);
        } else {
            QueryWrapper<Course> wrapper = new QueryWrapper<>();
            // 1、课程类型id
            if (course.getCoursetypeid() != null) {
                wrapper.eq("coursetypeid", course.getCoursetypeid());
            }
            // 模糊查询 课程名字 coursetitle
            wrapper.like(course.getCoursetitle() != null, "coursetitle", course.getCoursetitle());

            //2、查询条件：管理员增加：审核状态，是否推荐，课程状态三个查询条件；
            // 课程状态 -1--全部  0--未发布 1--发布 2--关闭
            if (course.getCoursestate() != null) {
                // 课程状态 = -1-->查询全部
                if (course.getCoursestate() != -1) {
                    wrapper.eq("coursestate", course.getCoursestate());
                }
            }
            // 是否推荐 -1--全部 0--不推荐 1--推荐
            if (course.getCourserecommended() != null) {
                if (course.getCourserecommended() != -1) {
                    wrapper.eq("courserecommended", course.getCourserecommended());
                }
            }
            // 审核状态  -1--全部 0--未审 1--通过 2--未通过
            if (course.getCourseaudit() != null) {
                if (course.getCourseaudit() != -1) {
                    wrapper.eq("courseaudit", course.getCourseaudit());
                }
            }
            // 增加按（课程排序: 课程评分，课程点击次数，评论次数）进行（0=asc/1=desc）排序的功能。
            // 自定义 数据库中没有 sort排序 ,0=asc 1=desc
            // SortBy:用什么排序 ,0=课程评分 coursescore ，1=课程点击次数 coursepullcount，2=评论次数 coursecommentcount
            if (course.getSort() != null) {
                if (course.getSort() == 0) {
                    //自定义 SortBy:用什么排序 ,0=课程评分，1=课程点击次数，2=评论次数
                    wrapper.orderByAsc(course.getSortBy() == 0, "coursescore");
                    wrapper.orderByAsc(course.getSortBy() == 1, "coursepullcount");
                    wrapper.orderByAsc(course.getSortBy() == 2, "coursecommentcount");
                }
                if (course.getSort() == 1) {
                    wrapper.orderByDesc(course.getSortBy() == 0, "coursescore");
                    wrapper.orderByDesc(course.getSortBy() == 1, "coursepullcount");
                    wrapper.orderByDesc(course.getSortBy() == 2, "coursecommentcount");
                }
            } else {
                // 按课程id进行 排序的功能，降序
                wrapper.orderByDesc("courseid");
            }
            return mapper.selectPage(page, wrapper);
        }
    }

    /**
     * 创建课程
     * <p>
     * 必有值:  登录用户的教师id
     * <p>
     * 查询出：
     * 课程教师姓名（courseteachername）= 登录用户的姓名
     * 课程所属机构id(courseorgid) = 如果教师属于某个机构，那么录入登录用户所属机构的id；如果是独立教师，那么此项为null
     */
    @Override
    public int insertCourse(Course course, String token) {
        // 根据登录用户id查询出: sysuser表登录用户的姓名 teacher表用户的教师id 用户所属机构的id
        CurrentUser user = tools.getCurrentUserFromRedis(token);
        // 用户信息
        if (user.getTecid() == null & user.getUser().getUsertruename() == null) {
            return 0;
        }
        // 课程状态（coursestate）=0（未发布）
        course.setCoursestate(0);
        // 审核状态
        course.setCourseaudit(0);

        // coursecreatetime=当前时间
        course.setCoursecreatetime(new Date());
        // 最后更新时间(courseupdatetime)=当前时间
        course.setCourseupdatetime(new Date());
        if (course.getCoursescore() == null) {
            // 课程评分（coursescore）= 5 （默认评分为5。评分范围【0-10】）
            course.setCoursescore(new BigDecimal(5.00));
        }

        // 课程点击次数（coursepullcount）= 0
        course.setCoursepullcount(0);

        // 是否推荐（courserecommended）=0
        course.setCourserecommended(0);

        // 课程过期时间 coursevaliddays 前端没有传默认730 两年
        if (course.getCoursevaliddays() == null) {
            course.setCoursevaliddays(730);
        }
        if (course.getCoursesort() == null) {
            // 课程排序（coursesort）=500（默认排序都为500）
            course.setCoursesort(500);
        }
        // 评论次数（coursecommentcount）=0
        course.setCoursecommentcount(0);
        // 课程所属机构id(courseorgid) = 如果教师属于某个机构，
        // 那么录入登录用户所属机构的id；如果是独立教师，那么此项为null
        if (user.getOrgid() != null) {
            course.setCourseorgid(user.getOrgid());
        }
        // 课程教师id（courseteacherid）= 登录用户的教师id
        if (user.getTecid() != null) {
            course.setCourseteacherid(user.getTecid());
        }
        // 是否启用易币 1--开启 0--不开启
        if (course.getCoursecoinused() == null) {
            course.setCoursecoinused(0);
            //设置当虚拟币为空时 设置为0
            // 课程虚拟币价格 coursecoinprice
            course.setCoursecoinprice(new BigDecimal(0.00));
            // 最多使用虚拟币数量
            course.setCoursecoinmaxpoint(new BigDecimal(0.00));
        }
        // coursetecorg 1--教师 2--机构
        if (course.getCoursetecorg() == null) {
            course.setCoursetecorg(2);
        }
        // 课程教师姓名（courseteachername）= 登录用户的姓名
        if (user.getUser().getUsertruename() != null) {
            course.setCourseteachername(user.getUser().getUsertruename());
        }
        return mapper.insert(course);
    }


    /**
     * 根据课程id 获取课程的总课时数量
     *
     * @param courseId
     * @return int
     */
    @Override
    public Integer selectCourseLessonNum(Integer courseId) {
        return lessonMapper.selectCourseLessonNum(courseId);
    }

    /**
     * 查询出所有可用的的课程  临时后台管理用
     *
     * @return List<Course>
     */
    @Override
    public List<Course> selectCourseList() {
        return mapper.selectCourseList();
    }

    /**
     * 创建线下课程 Offlineshowattrconfig对象
     * 1、根据用户所在机构查询出机构的简称
     * 2、保存课程信息
     * 3、保存课程显示的信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer insertCourses(CourseOfflineshowattrconfigDto courses, String token) {
        try {
            CurrentUser user = tools.getCurrentUserFromRedis(token);
            if (user == null) {
                return -2;
            }
            // 1 根据用户所在机构查询出机构的简称
            if (user.getOrgid() != null) {
                // 课程所属机构id(courseorgid) = 如果教师属于某个机构，
                // 那么录入登录用户所属机构的id；如果是独立教师，那么此项为null
                courses.setCourseorgid(user.getOrgid());
                Organization organization = oMapper.selectById(user.getOrgid());
                // 设置机构简称
                courses.setClassorg(organization.getField1());
            }
            // 2、保存课程信息
            int insertCourseId = this.insertCourse(courses, user);
            if (insertCourseId == 0) {
                throw new Exception("创建课程信息失败");
            }
            // 3、保存课程显示的信息
            // 设置课程id
            courses.getOfflineshowattrconfig().setCourseid(insertCourseId);
            int insert = ofMapper.insert(courses.getOfflineshowattrconfig());
            if (insert == 0) {
                throw new Exception("创建课程信息失败");
            }
            // 创建成功
            return 1;
        } catch (Exception e) {
            e.printStackTrace();
            // @Transactional和try catch捕获异常会让注解失效
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return 0;
        }
    }

    /**
     * 添加课程信息
     *
     * @param course
     * @param user
     * @return int 添加课程信息
     * 添加成功返回课程id
     * 添加失败返回0
     */
    private int insertCourse(Course course, CurrentUser user) {
        // 课程状态（coursestate）=0（未发布）
        course.setCoursestate(0);
        // 审核状态
        course.setCourseaudit(0);
        // coursecreatetime=当前时间
        course.setCoursecreatetime(new Date());
        // 最后更新时间(courseupdatetime)=当前时间
        course.setCourseupdatetime(new Date());
        if (course.getCoursescore() == null) {
            // 课程评分（coursescore）= 5 （默认评分为5。评分范围【0-10】）
            course.setCoursescore(new BigDecimal(5.00));
        }

        // 课程点击次数（coursepullcount）= 0
        course.setCoursepullcount(0);

        // 是否推荐（courserecommended）=0
        course.setCourserecommended(0);

        // 课程过期时间 coursevaliddays 前端没有传默认730 两年
        if (course.getCoursevaliddays() == null) {
            course.setCoursevaliddays(730);
        }
        if (course.getCoursesort() == null) {
            // 课程排序（coursesort）=500（默认排序都为500）
            course.setCoursesort(500);
        }
        // 评论次数（coursecommentcount）=0
        course.setCoursecommentcount(0);

        // 课程教师id（courseteacherid）= 登录用户的教师id
        if (user.getTecid() != null) {
            course.setCourseteacherid(user.getTecid());
        }
        // 是否启用易币 1--开启 0--不开启
        if (course.getCoursecoinused() == null) {
            course.setCoursecoinused(0);
            //设置当虚拟币为空时 设置为0
            // 课程虚拟币价格 coursecoinprice
            course.setCoursecoinprice(new BigDecimal(0.00));
            // 最多使用虚拟币数量
            course.setCoursecoinmaxpoint(new BigDecimal(0.00));
        }
        // coursetecorg 1--教师 2--机构
        if (course.getCoursetecorg() == null) {
            course.setCoursetecorg(2);
        }
        // 课程教师姓名（courseteachername）= 登录用户的姓名
        if (user.getUser().getUsertruename() != null) {
            course.setCourseteachername(user.getUser().getUsertruename());
        }
        int insert = mapper.insert(course);
        if (insert > 0) {
            return course.getCourseid();
        } else {
            return 0;
        }
    }

    /**
     * 修改线下课程使用数据
     * 如果该课程不存对应的显示控制，则进行创建一个显示控制
     *
     * @param courses 必要条件中的课程id（courseid、showconfigid）
     * @return int
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateOfflineCourse(CourseOfflineshowattrconfigDto courses) {
        try {
            // 是否启用易币 1--开启 0--不开启
            if (courses.getCoursecoinused() != null && courses.getCoursecoinused() == 0) {
                //设置当虚拟币为空时 设置为0
                // 课程虚拟币价格 coursecoinprice
                courses.setCoursecoinprice(new BigDecimal(0.00));
                // 最多使用虚拟币数量
                courses.setCoursecoinmaxpoint(new BigDecimal(0.00));
            }
            int updateById = mapper.updateById(courses);
            if (updateById == 0) {
                throw new Exception("修改课程信息失败");
            }
            if (courses.getOfflineshowattrconfig().getShowconfigid() == null) {
                // 设置课程id
                courses.getOfflineshowattrconfig().setCourseid(courses.getCourseid());
                int insert = ofMapper.insert(courses.getOfflineshowattrconfig());
                if (insert == 0) {
                    throw new Exception("修改课程信息失败");
                }
            } else {
                int update = ofMapper.updateById(courses.getOfflineshowattrconfig());
                if (update == 0) {
                    throw new Exception("修改课程信息失败");
                }
            }
            return 1;
        } catch (Exception e) {
            e.printStackTrace();
            // @Transactional和try catch捕获异常会让注解失效
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return 0;
        }
    }

    /**
     * 根据 课程id(courseid) 查询线下课程数据
     *
     * @param courseId
     * @return CourseOfflineshowattrconfigDto
     */
    @Override
    public CourseOfflineDto selectOfflineCourseById(Integer courseId) {
        return mapper.selectOfflineCourseById(courseId);
    }
}
